<?php

//XPath query to run
$xpath=$_GET['x'];

//When magic_quotes are on, strip extra backslashes
if (get_magic_quotes_gpc())
    $xpath=stripcslashes($xpath);

//Result container
$result=Array(  "success"=>0,
                "xpath1"=>"",
                "xpath2"=>"",
                "message"=>""
             );

try
{
    //Parse the XPath
    $r=vxp_parse($xpath);

    //Get default AST as a PHP Array
    $tree=vxp_tree($r);
    //Generate jQuery treeview markup
    $result['xpath1']=toTreeview($tree);


    //Get XPath 2.1 AST as a PHP Array (reuses the $r resource)
    $tree=vxp_tree($r,XPATH_21);
    //Generate jQuery treeview markup
    $result['xpath2']=toTreeview($tree);

    //Success
    $result['success']=1;
}
catch (XPathException $e)
{
    $message="";            /* user friendly message */
    $line=$e->xpath_line;   /* the offending line */
    $col=$e->xpath_column;  /* the offending column */

    /* Output different error messages, depending on the code */
    switch ($e->getCode())
    {   
        /* Generic failures */
        case XPathException::ERROR:
        case XPathException::MEMORY:$message="The server is experiencing ".
                                    "technical difficulties. Please try again".
                                    " later.";
                                    break;
        /* Syntax errors */
        case XPathException::SYNTAX:$message=str_replace('$end','end of query',
                                                         $e->getMessage())
                                             ." on line $line, column $col.";
                                    
                                    break;
        /* Lexer errors, message contains offending character */
        case XPathException::BAD_CHAR:$message="Unexpected character &quot;".
                                    htmlspecialchars($e->getMessage()).
                                    "&quot; on line $line, column $col.";
    }
    
    /* Store the final message */
    $result['message']=ucfirst($message);
}

/* Output the result as JSON */
echo json_encode($result);



/** Generates jQuery treeview markup out of an AST.
* Calls nodeToHTML() and returns the result
* @return an HTML string with <ul> as the root element
*/
function toTreeview(Array &$tree)
{
    $result="<ul>";
    nodeToHTML($tree,$result);
    $result.="</ul>";

    return $result;
}

/** Processes each node in the AST and appends <li> elements as necessary.
* If the node has children, an <ul> element is inserted and the function calls
* itself recursively.
*/
function nodeToHTML(Array $node, &$result)
{
    $result.="<li>";

    /* Output the name of the node */
    if (isset($node['name']))
        $result.="<span>".$node['name']."</span>";

    /* Append the value of the node, if it exists */
    if (isset($node['value']))
        $result.="<span class='value'>".$node['value']."</span>";

    /* Process all children */
    if (isset($node['children']))
    {
        $result.="<ul>";
        foreach ($node['children'] as &$child)
            nodeToHTML($child,$result);
        $result.="</ul>";
    }

    $result.="</li>";
}
